﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using AForge;
using AForge.Imaging.Filters;
using AForge.Imaging;
using AForge.Math.Geometry;

namespace Bildverarbeitung.CGFilter
{
    class HesseSebastianFilter : Bildverarbeitung.IFilter
    {
        
        private Bitmap imggray;

        public Bitmap Imggray
        {
            get { return imggray; }           
        }

        public HesseSebastianFilter()
        {
            
        }

        public Bitmap GetImageWithDoor(Bitmap img)
        {
            Bitmap p = (Bitmap)img.Clone();
            Grayscale grayF = new Grayscale(0.2125, 0.7154, 0.0721);
            SobelEdgeDetector sed = new SobelEdgeDetector();
            CannyEdgeDetector ced = new CannyEdgeDetector();

            GaussianBlur gb = new GaussianBlur();
            Invert inv = new Invert();
            Dilatation dil = new Dilatation();
            Median m = new Median();

            ContrastStretch cs = new ContrastStretch();
            ContrastCorrection cc = new ContrastCorrection(2.0f);
            IterativeThreshold ith = new IterativeThreshold(0, 50);

            cc.ApplyInPlace(img);
            imggray = grayF.Apply(img);
            cs.ApplyInPlace(imggray);
            sed.ApplyInPlace(imggray);
            gb.ApplyInPlace(imggray);
            ith.ApplyInPlace(imggray);
            dil.ApplyInPlace(imggray);
            m.ApplyInPlace(imggray);
            ced.ApplyInPlace(imggray);

            MoravecCornersDetector scd = new MoravecCornersDetector();
            List<IntPoint> corners = scd.ProcessImage(imggray);
            List<Rectangle> CornerRect = new List<Rectangle>();
            UnmanagedImage pu = UnmanagedImage.FromManagedImage(p);
            SaturationCorrection sat = new SaturationCorrection(-0.2f);
            sat.ApplyInPlace(img);
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.MaxWidth = imggray.Width / 3;
            blobCounter.MinWidth = imggray.Width / 5;
            blobCounter.MinHeight = imggray.Height / 5;
            blobCounter.FilterBlobs = true;
            blobCounter.ProcessImage(imggray);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            Pen bluePen = new Pen(Color.Blue);
            SolidBrush blueBrush = new SolidBrush(Color.Blue);

            for (int j = 0, n = blobs.Length; j < n; j++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[j]);
                List<IntPoint> corners3 = PointsCloud.FindQuadrilateralCorners(edgePoints);
                //Drawing.Polygon(pu, corners3, Color.Blue);
                Rectangle re = getRect(corners3);
                Console.WriteLine(re.X + "|" + re.Y + "||" + re.Width + "|" + re.Height);
                Drawing.FillRectangle(pu, re, Color.Blue);
                foreach (IntPoint po in corners3)
                {
                    Drawing.FillRectangle(pu, new Rectangle(po.X - 4, po.Y - 4, 9, 9), Color.Red);
                }


                Console.WriteLine();
            }
            //HoughLineTransformation hlt = new HoughLineTransformation();
            //hlt.ProcessImage(imggray);
            //HoughLine[] lines = hlt.GetMostIntensiveLines(40);

            //foreach (HoughLine l in lines)
            //{
            //    int rad = l.Radius;
            //    double theta = l.Theta;

            //    int wM = p.Width >> 1;
            //    int hM = p.Height >> 1;

            //    double x0 = 0, x1 = 0, y0 = 0, y1 = 0;
            //    if (rad < 0)
            //    {
            //        theta += 180;
            //        rad = -rad;
            //    }
            //    theta = (theta / 180) * Math.PI;

            //    if (l.Theta != 0)
            //    {
            //        x0 = -wM;
            //        x1 = wM;

            //        y0 = (-Math.Cos(theta) * x0 + rad) / Math.Sin(theta);
            //        y1 = (-Math.Cos(theta) * x1 + rad) / Math.Sin(theta);
            //    }
            //    else
            //    {
            //        x0 = l.Radius;
            //        x1 = l.Radius;
            //        y0 = hM;
            //        y1 = -hM;
            //    }
            //    Drawing.Line(pu,
            //                new IntPoint((int)x0 + wM, hM - (int)y0),
            //                new IntPoint((int)x1 + wM, hM - (int)y1),
            //                Color.Red);

            //}
            //return img;
            return pu.ToManagedImage(false);
        }

        private Rectangle getRect(List<IntPoint> corners)
        {
            IntPoint p1, p4;
            p1 = corners[0];
            p4 = corners[0];

            for (int i = 0; i < corners.Count; i++)
            {
                if (p1.EuclideanNorm() > corners[i].EuclideanNorm())
                {
                    p1 = corners[i];
                }
                if (p4.EuclideanNorm() < corners[i].EuclideanNorm())
                {
                    p4 = corners[i];
                }
            }
            return new Rectangle(p1.X, p1.Y, (p4.X - p1.X), (p4.Y - p1.Y));
        }      

        public String GetName()
        {
            return ("Hesse Sebastian");
        }
    }
}
